import queue
import threading
import cv2 as cv
import subprocess as sp

class Live(object):
    def __init__(self, command="", rtmp_url="", camera_path=""):
        self.frame_queue = queue.Queue()
        self.command = command
        # 自行设置
        self.rtmpUrl = rtmp_url
        self.camera_path = camera_path

    def read_frame(self):
        print("开启推流")
        cap = cv.VideoCapture(self.camera_path)

        # Get video information
        fps = int(cap.get(cv.CAP_PROP_FPS))
        print(fps)
        width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))
        print(width)
        height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))
        print(height)
        # ffmpeg command
        self.command = ['C:\\Users\\EDZ\\Downloads\\ffmpeg\\ffmpeg-20191211-4110029-win64-static\\bin\\ffmpeg',
                        '-re',
                        # '-y', # 覆盖输出文件而不询问
                        # '-f', 'rawvideo',
                        '-i', self.camera_path,# 输入文件名
                        '-vcodec', 'copy',
                        '-acodec','copy',
                        # '-pix_fmt', 'bgr24',  #像素格式
                        '-s', "{}x{}".format(width, height),  # 分辨率
                        '-r', str(fps),
                        # '-c:v', 'libx264',
                        # '-pix_fmt', 'yuv420p',
                        # '-preset', 'ultrafast',
                        '-f', 'flv',  #格式是flv的
                        self.rtmpUrl]

        # read webcamera
        while (cap.isOpened()):
            ret, frame = cap.read()
            if not ret:
                print("Opening camera is close")
                break

            # put frame into queue
            print("推送流到队列中")
            self.frame_queue.put(frame)

    def push_frame(self):
        # 防止多线程时 command 未被设置
        while True:
            if len(self.command) > 0:
                # 管道配置
                p = sp.Popen(self.command, stdin=sp.PIPE)
                break


        while True:
            if self.frame_queue.empty() != True:
                frame = self.frame_queue.get()
                # process frame
                # 你处理图片的代码
                # write to pipe
                print('将流写入管道')
                # p.stdin.write(frame.tostring())
                try:
                    p.stdin.write(frame.tostring()) ## 当没有数据的时候会报错,所以需要对他进行一些异常捕获
                except Exception as e:
                    print(e)
                    print('结束写入')

    def run(self):
        thread1 = threading.Thread(target=Live.read_frame, args=(self,))
        thread1.start()
        thread2 = threading.Thread(target=Live.push_frame, args=(self,))
        thread2.start()

if __name__ == '__main__':

    live = Live(rtmp_url='rtmp://47.101.189.16:1935/live_test/b',camera_path="d.mp4")
    live.run()
# ffmpeg -re -i r.mp4 -vcodec copy -acodec copy -f flv rtmp://47.101.189.16/live_test/bus